package com.example.controller;


import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.example.common.annotation.LogAnno;
import com.example.common.result.Result;
import com.example.controller.base.BaseController;
import com.example.entity.Menu;
import com.example.entity.RoleMenu;
import com.example.service.IMenuService;
import com.example.service.IRoleMenuService;
import com.example.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.util.StringUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.security.Principal;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author ptuDai
 * @since 2022-03-05
 */
@RestController
@RequestMapping("/menu")
public class MenuController extends BaseController {
    @Autowired
    private IMenuService menuService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IRoleMenuService roleMenuService;

    /**
     * 获取当前用户的菜单栏以及权限
     */
    @PostMapping("/nav")
    public Result nav(Principal principal) {
        String userName = principal.getName();
        // ROLE_Admin,sys:user:save
        String[] authorities = StringUtils.tokenizeToStringArray(userService.getUserAuthorityInfo(userName), ",");
        final Map<Object, Object> navAuthoritiesMap = MapUtil.builder().put("nav", menuService.getCurrentUserNav()).put("authorities", authorities).map();
        return Result.ok().data(navAuthoritiesMap);
    }

    @LogAnno(operateType = "查看菜单信息")
    @GetMapping("/info/{id}")
    @PreAuthorize("hasAuthority('sys:menu:edit')")
    public Result info(@PathVariable("id") Integer id) {
        return Result.ok().data(menuService.getById(id));
    }

    @GetMapping("/tree")
    @PreAuthorize("hasAuthority('sys:menu:list')")
    public Result list() {
        List<Menu> menus = menuService.tree();
        return Result.ok().data(menus);
    }

    @LogAnno(operateType = "新增菜单")
    @PostMapping("/save")
    @PreAuthorize("hasAuthority('sys:menu:add')")
    public Result save(@Validated @RequestBody Menu sysMenu) {
        menuService.save(sysMenu);
        return Result.created().data(sysMenu);
    }

    @LogAnno(operateType = "更新菜单")
    @PostMapping("/update")
    @PreAuthorize("hasAuthority('sys:menu:edit')")
    public Result update(@Validated @RequestBody Menu sysMenu) {
        if (sysMenu.getParentId().equals(sysMenu.getId())){
            return Result.unUpdated().message("不能选择自己为上级");
        }
        menuService.updateById(sysMenu);
        // 清除所有与该菜单相关的权限缓存
        redisService.clearUserAuthorityInfoByMenuId(sysMenu.getId());
        return Result.update().data(sysMenu);
    }

    @LogAnno(operateType = "删除菜单")
    @PostMapping("/delete/{id}")
    @PreAuthorize("hasAuthority('sys:menu:del')")
    public Result delete(@PathVariable Integer id) {
        int count = menuService.count(new QueryWrapper<Menu>().eq("parent_id", id));
        if (count > 0) {
            return Result.unDeleted().message("请先删除子菜单");
        }
        // 先清除所有与该菜单相关的权限缓存
        redisService.clearUserAuthorityInfoByMenuId(id);
        menuService.removeById(id);
        // 同步删除
        roleMenuService.remove(new QueryWrapper<RoleMenu>().eq("menu_id", id));
        return Result.ok();
    }
}
